package com.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.core.sysConfig.bo.SysConfigBo;
import com.core.visaInfo.bo.VisaInfoBo;
import com.core.visaInfo.pojo.VisaInfo;
import com.util.exception.ComRuntimeException;

public class DownloadServlet extends HttpServlet {
	private static final long serialVersionUID = 3394244267156351653L;
	private static Logger log = Logger.getLogger(DownloadServlet.class);
	// private String enc = "utf-8";

	@Autowired
	private VisaInfoBo visaInfoBo;

	@Autowired
	private SysConfigBo sysConfigBo;

	public DownloadServlet() {
		super();
	}

	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		WebApplicationContextUtils.getWebApplicationContext(getServletContext()).getAutowireCapableBeanFactory().autowireBean(this);
	}

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		processRequest(request, response);
	}

	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		processRequest(request, response);
	}

	private void processRequest(HttpServletRequest request, HttpServletResponse response) {
		String fileType = request.getParameter("fileType");
		if (Consts.FILE_TYPE_RETURN_REPORT_EXCEL.equals(fileType)) {
			downloadReturnReportExcel(request, response);
		} else {
			log.error("unknow file type: " + fileType);
		}
	}

	private void downloadReturnReportExcel(HttpServletRequest request, HttpServletResponse response) {
		InputStream inStream = null;
		ServletOutputStream servletOS = null;

		try {
			String visaInfoId = request.getParameter("visaInfoId");
			if (StringUtil.isEmpty(visaInfoId) || !NumberUtil.isLong(visaInfoId)) {
				throw new ComRuntimeException("visaInfoId is null or not a Long number");
			}

			VisaInfo visaInfo = visaInfoBo.getById(Long.valueOf(visaInfoId));
			if (visaInfo == null) {
				throw new ComRuntimeException("cannot find visa info in database, viseInfoId: " + visaInfoId);
			}

			if (visaInfo.getReturnReportUploadTime() == null) {
				throw new ComRuntimeException("return report upload time is null, excel may not be uploaded, viseInfoId: " + visaInfoId);
			}

			String rootFold = sysConfigBo.getByKeyNo(Consts.FOLD_ROOT).getKey_value();
			String returnReportFold = sysConfigBo.getByKeyNo(Consts.FOLD_RETURN_REPORT_UPLOAD).getKey_value();
			String monthFold = DateUtil.format2ym6(visaInfo.getReturnReportUploadTime());

			String excelFoldPath = rootFold + File.separator + returnReportFold + File.separator + monthFold;
			// xls
			String fileName = visaInfo.getId() + ".xls";
			File excelFile = new File(excelFoldPath + File.separator + fileName);
			if (!excelFile.exists()) {
				// 如果xlx找不到，试试xlsx
				fileName = visaInfo.getId() + ".xlsx";
				excelFile = new File(excelFoldPath + File.separator + fileName);
			}

			// xls和xlsx文件都不存在
			if (!excelFile.exists()) {
				throw new ComRuntimeException("return report excel file not found, viseInfoId: " + visaInfoId + ", excel path: " + excelFoldPath + File.separator + visaInfo.getId() + ".xls(x)");
			}

			// start reponse file
			response.reset();
			response.setContentType(getContentType(fileName));
			response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(fileName, "utf-8") + "\"");

			long fileLength = excelFile.length();
			response.setContentLengthLong(fileLength);

			if (fileLength > 0) {
				inStream = new FileInputStream(excelFile);
				servletOS = response.getOutputStream();

				byte[] buf = new byte[4096];
				int readLength;

				while (((readLength = inStream.read(buf)) != -1)) {
					try {
						servletOS.write(buf, 0, readLength);
					} catch (IOException e2) {
						// ignore
					}
				}

				try {
					servletOS.flush();
				} catch (Exception e) {
					// user canceled
				}
			}

		} catch (Throwable e) {
			log.error("error", e);
		} finally {
			if (inStream != null) {
				try {
					inStream.close();
				} catch (IOException e) {
					// ignored
				}
			}

			if (servletOS != null) {
				try {
					servletOS.close();
				} catch (IOException e) {
					// ignored
				}
			}
		}

	}

	private String getContentType(String fileName) {
		String fileNameTmp = fileName.toLowerCase();
		String ret = "";

		if (fileNameTmp.endsWith("swf")) {
			ret = "application/x-shockwave-flash";
		} else if (fileNameTmp.endsWith("gif")) {
			ret = "image/gif";
		} else if (fileNameTmp.endsWith("jpg")) {
			ret = "image/jpeg";
		} else if (fileNameTmp.endsWith("jpeg")) {
			ret = "image/jpeg";
		} else if (fileNameTmp.endsWith("rtf")) {
			ret = "application/msword";
		} else if (fileNameTmp.endsWith("doc")) {
			ret = "application/msword";
		} else if (fileNameTmp.endsWith("docx")) {
			ret = "application/msword";
		} else if (fileNameTmp.endsWith("xls")) {
			ret = "application/vnd.ms-excel";
		} else if (fileNameTmp.endsWith("xlsx")) {
			ret = "application/vnd.ms-excel";
		} else if (fileNameTmp.endsWith("jpe")) {
			ret = "image/jpeg";
		} else if (fileNameTmp.endsWith("zip")) {
			ret = "application/zip";
		} else if (fileNameTmp.endsWith("txt")) {
			ret = "text/plain";
		} else if (fileNameTmp.endsWith("rar")) {
			ret = "application/rar";
		} else if (fileNameTmp.endsWith("ppt")) {
			ret = "application/vnd.ms-powerpoint";
		} else if (fileNameTmp.endsWith("html")) {
			ret = "text/html";
		} else if (fileNameTmp.endsWith("htm")) {
			ret = "text/html";
		} else if (fileNameTmp.endsWith("tif")) {
			ret = "image/tiff";
		} else if (fileNameTmp.endsWith("tiff")) {
			ret = "image/tiff";
		} else if (fileNameTmp.endsWith("pdf")) {
			ret = "application/pdf";
		} else {
			ret = "application/x-msdownload";
		}
		return ret;
	}

}